package prom

import (
	"bytes"
	"encoding/json"
	"fmt"
	"gluenet/internal/pkg/infra"
	"io/ioutil"
	"net/http"
	"net/url"
)

type MetricResp struct {
	Status string     `json:"status"`
	Data   MetricData `json:"data"`
}

type MetricData struct {
	ResultType string              `json:"resultType"`
	Result     []infra.MetricsData `json:"result"`
}

func (r *cli) GetMetrics(query map[string]string, time string) (*MetricData, error) {
	var raw bytes.Buffer
	kind, ok := query["__name__"]
	if !ok {
		return nil, fmt.Errorf("must include __name__")
	}
	raw.WriteString(fmt.Sprintf("{__name__=\"%s\"", kind))
	for k, v := range query {
		if k != "__name__" && v != "" {
			raw.WriteString(fmt.Sprintf(",%s=\"%s\"", k, v))
		}
	}
	raw.WriteString("}")
	raw.String()

	objUrl, _ := url.Parse(r.url)
	q := url.Values{}
	q.Set("query", raw.String())
	q.Set("time", time)
	objUrl.RawQuery = q.Encode()

	resp, err := http.Get(objUrl.String())
	if err != nil {
		return nil, err
	}

	bts, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	var data = MetricResp{}
	err = json.Unmarshal(bts, &data)
	if err != nil {
		return nil, err
	}

	if data.Status != "success" {
		return nil, fmt.Errorf("req error %v", data.Status)
	}
	//http.
	return &data.Data, nil
}

func (r *cli) FlexibleQuery(query map[string]string, time string) (*MetricData, error) {
	var raw bytes.Buffer
	kind, ok := query["__name__"]
	if !ok {
		return nil, fmt.Errorf("must include __name__")
	}
	raw.WriteString(fmt.Sprintf("{__name__=\"%s\"", kind))
	for k, v := range query {
		if k != "__name__" {
			raw.WriteString(fmt.Sprintf(",%s=~\"%s.*\"", k, v))
		}
	}
	raw.WriteString("}")
	a := raw.String()
	fmt.Println(a)

	objUrl, _ := url.Parse(r.url)
	q := url.Values{}
	q.Set("query", raw.String())
	q.Set("time", time)
	objUrl.RawQuery = q.Encode()

	resp, err := http.Get(objUrl.String())
	if err != nil {
		return nil, err
	}

	bts, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	var data = MetricResp{}
	err = json.Unmarshal(bts, &data)
	if err != nil {
		return nil, err
	}

	if data.Status != "success" {
		return nil, fmt.Errorf("req error %v", data.Status)
	}
	//http.
	return &data.Data, nil
}

func (r *cli) Query(query string, time string) (*MetricData, error) {
	objUrl, _ := url.Parse(r.url)
	q := url.Values{}
	q.Set("query", query)
	q.Set("time", time)
	objUrl.RawQuery = q.Encode()

	resp, err := http.Get(objUrl.String())
	if err != nil {
		return nil, err
	}

	bts, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	var data = MetricResp{}
	err = json.Unmarshal(bts, &data)
	if err != nil {
		return nil, err
	}

	if data.Status != "success" {
		return nil, fmt.Errorf("req error %v", data.Status)
	}
	//http.
	return &data.Data, nil
}
